home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / jabber / JabberBuddy.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  18.4 KB  |  526 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import common
  5. import hashlib
  6. import jabber
  7. from jabber import JID, Presence
  8. from util import callsback, Storage as S, cproperty, odict, threaded, urlcacheopen
  9. from common.actions import action
  10. from jabber.objects.nick import NICK_NS, Nick
  11. from common import pref
  12. from gui import skin
  13. from urllib import quote
  14. from pyxmpp.jabber.vcard import VCardString
  15.  
  16. VCardString.decode = lambda s, *a: s.value.decode(*a)
  17. from jabber import VCard
  18. from util.observe import ObservableProperty as oproperty
  19. import logging
  20. log = logging.getLogger('jabber.buddy')
  21. GTALK = 'gtalk'
  22. GTALK_DOMAINS = ('gmail.com', 'googlemail.com')
  23. JABBER = 'jabber'
  24.  
  25. def isGTalk(resource):
  26.     if not isinstance(resource, basestring):
  27.         return False
  28.     
  29.     reslower = resource.lower()
  30.     return (any,)((lambda .0: for x in .0:
  31. reslower.startswith(x))(('talk.', 'gmail.', 'talkgadget', 'ics')))
  32.  
  33.  
  34. no_widget = lambda self: None if getattr(self, 'iswidget', False) else True
  35. ADDRESS_KEYS = 'street,extadr,locality,region,pcode,ctry'.split(',')
  36. WORK_KEYS = 'company department postition role'.split()
  37. SUBSCRIPTION_TO = ('to', 'both')
  38. SUBSCRIPTION_FROM = ('from', 'both')
  39.  
  40. class JabberBuddy(common.buddy):
  41.     
  42.     def __init__(self, jabber_, jid, rosteritem = None):
  43.         uname = JID(jid).bare().as_unicode()
  44.         self.jid = JID(jid).bare()
  45.         self.username = uname
  46.         self.resources = { }
  47.         self.subscription = None if rosteritem else None
  48.         self.rostername = None if rosteritem else None
  49.         self.ask = None if rosteritem else None
  50.         self.groups = None if rosteritem else []
  51.         self.profile = False
  52.         common.buddy.__init__(self, uname, jabber_)
  53.         self._gen_pretty_profile()
  54.         self.pending_adds = set()
  55.  
  56.     
  57.     def __call__(self, item):
  58.         self.subscription = item.subscription
  59.         self.ask = item.ask
  60.         self.rostername = item.name
  61.         self.groups = item.groups
  62.         self.check_subscription()
  63.         return self
  64.  
  65.     
  66.     def sort(self, cmp = cmp, key = (lambda x: x), reverse = False):
  67.         pass
  68.  
  69.     
  70.     def check_subscription(self):
  71.         if self.subscription not in SUBSCRIPTION_TO and self.resources and self is not getattr(self.protocol, 'self_buddy', sentinel):
  72.             self.resources.clear()
  73.             self.notify()
  74.         
  75.  
  76.     
  77.     def service(self):
  78.         if self.jid.domain in GTALK_DOMAINS:
  79.             return GTALK
  80.         else:
  81.             return JABBER
  82.  
  83.     service = property(service)
  84.     
  85.     def serviceicon(self):
  86.         if self.jid.domain in GTALK_DOMAINS or any((lambda .0: for j in .0:
  87. isGTalk(j.resource))(self.resources)):
  88.             service = GTALK
  89.         else:
  90.             service = JABBER
  91.         return skin.get('serviceicons.' + service)
  92.  
  93.     serviceicon = property(serviceicon)
  94.     
  95.     def id(self):
  96.         return self.jid
  97.  
  98.     id = property(id)
  99.     
  100.     def away(self):
  101.         if self.service == GTALK:
  102.             if self.resources and not (self.idle):
  103.                 pass
  104.             return not any((lambda .0: for r in .0:
  105. r.available)(self.resources.itervalues()))
  106.         elif self.resources:
  107.             pass
  108.         return all((lambda .0: for r in .0:
  109. r.away)(self.resources.itervalues()))
  110.  
  111.     away = property(away)
  112.     
  113.     def mobile(self):
  114.         return False
  115.  
  116.     mobile = property(mobile)
  117.     
  118.     def blocked(self):
  119.         return False
  120.  
  121.     blocked = property(blocked)
  122.     
  123.     def online(self):
  124.         return bool(self.resources)
  125.  
  126.     online = property(online)
  127.     
  128.     def idle(self):
  129.         if self.service == GTALK:
  130.             if self.resources:
  131.                 pass
  132.             return all((lambda .0: for r in .0:
  133. r.idle)(self.resources.itervalues()))
  134.         else:
  135.             return False
  136.  
  137.     idle = property(idle)
  138.     
  139.     def get_caps(self):
  140.         caps = common.buddy.get_caps(self)
  141.         for r in self.resources.values():
  142.             res = r.jid.resource
  143.             if res and not isGTalk(res):
  144.                 break
  145.                 continue
  146.         
  147.         return caps
  148.  
  149.     caps = property(get_caps)
  150.     
  151.     def _gen_pretty_profile(self):
  152.         profile = odict()
  153.         ok = False
  154.         fullname = self.vcard_get('fn')
  155.         if fullname:
  156.             profile['Full Name:'] = fullname
  157.             ok = True
  158.         
  159.         mapping = {
  160.             'birthday': ('bday',),
  161.             'email_address': ('email', 'address'),
  162.             'phone': ('tel', 'number'),
  163.             'company': ('org', 'name'),
  164.             'department': ('org', 'unit'),
  165.             'postition': ('title',),
  166.             'role': ('role',) }
  167.         for key in ('birthday', 'email_address', 'phone'):
  168.             val = self.vcard_get(*mapping[key])
  169.             if val is not None:
  170.                 profile[key.replace('_', ' ').title() + ':'] = val
  171.                 ok = True
  172.                 continue
  173.         
  174.         homepage = self.vcard_get('url')
  175.         if homepage:
  176.             profile['Website'] = (homepage, homepage)
  177.             ok = True
  178.         
  179.         about = self.vcard_get('desc')
  180.         if about:
  181.             if ok:
  182.                 profile['sep1'] = 4
  183.             
  184.             profile['Additional Information:'] = ''.join([
  185.                 '\n',
  186.                 about])
  187.         
  188.         
  189.         def prettyaddy(addict):
  190.             addy = []
  191.             
  192.             add = lambda s: addy.insert(0, s)
  193.             mstr = '%(street)s %(extadr)s %(locality)s %(region)s %(pcode)s %(ctry)s' % addict
  194.             if isinstance(mstr, unicode):
  195.                 mstr = mstr.encode('utf-8')
  196.             
  197.             murl = 'http://maps.google.com/maps?q=' + quote(mstr)
  198.             if addict.ctry:
  199.                 add('\n' + addict.ctry)
  200.             
  201.             if addict.pcode:
  202.                 add(addict.pcode)
  203.             
  204.             if addict.region:
  205.                 if addict.pcode:
  206.                     add(' ')
  207.                 
  208.                 add(addict.region)
  209.             
  210.             if addict.locality:
  211.                 if addict.region or addict.pcode:
  212.                     add(', ')
  213.                 
  214.                 add(addict.locality)
  215.             
  216.             if addict.extadr:
  217.                 if any((addict.locality, addict.region, addict.pcode)):
  218.                     add('\n')
  219.                 
  220.                 add(addict.extadr)
  221.             
  222.             if addict.street:
  223.                 if any((addict.locality, addict.region, addict.pcode, addict.extadr)):
  224.                     add('\n')
  225.                 
  226.                 add(addict.street)
  227.             
  228.             if addy:
  229.                 add([
  230.                     '(',
  231.                     (murl, 'map'),
  232.                     ')\n'])
  233.             
  234.             return addy
  235.  
  236.         address = self.vcard_get('adr')
  237.         if ok:
  238.             profile['sep3'] = 4
  239.         
  240.         for key in WORK_KEYS:
  241.             val = self.vcard_get(*mapping[key])
  242.             profile[key.title() + ':'] = val
  243.         
  244.         self.last_pretty_profile = profile
  245.         return profile
  246.  
  247.     
  248.     def pretty_profile(self):
  249.         return getattr(self, ('last_pretty_profile',), (lambda : self._gen_pretty_profile()))
  250.  
  251.     pretty_profile = property(pretty_profile)
  252.     
  253.     def get_status_message(self):
  254.         
  255.         try:
  256.             res = self.get_highest_priority_resource()
  257.             if res:
  258.                 if not res.status_message:
  259.                     pass
  260.                 return ''
  261.             else:
  262.                 return ''
  263.         except Exception:
  264.             e = None
  265.             log.warning('status_message(self) on %r: %r', self, e)
  266.             raise 
  267.  
  268.  
  269.     
  270.     def set_status_message(self, value):
  271.         r = self.get_highest_priority_resource()
  272.         if r:
  273.             old = r.status_message
  274.             r.status_message = value
  275.             self.notify('status_message', old, value)
  276.         
  277.  
  278.     status_message = property(get_status_message, set_status_message)
  279.     
  280.     def stripped_msg(self):
  281.         return self.status_message
  282.  
  283.     stripped_msg = property(stripped_msg)
  284.     
  285.     def status(self):
  286.         if self.subscription not in SUBSCRIPTION_TO and self is not getattr(self.protocol, 'self_buddy', sentinel):
  287.             return 'unknown'
  288.         elif not getattr(self, 'resources', []):
  289.             return 'offline'
  290.         elif not self.away:
  291.             return 'available'
  292.         else:
  293.             return 'away'
  294.  
  295.     status = property(status)
  296.     
  297.     def update_presence(self, presence, notify = True, buddy = None):
  298.         if not presence.get_from():
  299.             pass
  300.         buddy = buddy
  301.         presence_type = presence.get_type()
  302.         if not presence_type or presence_type == 'available':
  303.             old_length = len(self.resources)
  304.             self.resources[buddy] = jabber.resource(self.protocol, buddy, presence)
  305.             children = presence.xmlnode.get_children()
  306.             nicks = jabber.jabber_util.xpath_eval(presence.xmlnode, 'n:nick', {
  307.                 'n': NICK_NS })
  308.             if nicks:
  309.                 self.nick = Nick(nicks[0]).nick
  310.             
  311.             if self.jid.domain not in pref('digsby.guest.domains', []):
  312.                 self.protocol.get_buddy_icon(self.name)
  313.             
  314.         elif presence_type == 'unavailable':
  315.             if buddy in self.resources:
  316.                 del self.resources[buddy]
  317.             
  318.         
  319.         if notify:
  320.             self.notify('status')
  321.         
  322.  
  323.     
  324.     def get_highest_priority_resource(self):
  325.         return None if getattr(self, 'resources', []) else None
  326.  
  327.     
  328.     def set_vcard(self, stanza):
  329.         log.info('incoming vcard for %s', self)
  330.         self._vcard_incoming = False
  331.         q = stanza.get_query()
  332.         if not q:
  333.             return None
  334.         
  335.         
  336.         try:
  337.             vc = self.vcard = jabber.VCard(q)
  338.         except ValueError:
  339.             pass
  340.  
  341.         self._incoming_icon(vc.photo)
  342.         self._gen_pretty_profile()
  343.  
  344.     
  345.     def set_vc(self, vcard):
  346.         self._vcard = vcard
  347.  
  348.     
  349.     def get_vc(self):
  350.         return self._vcard
  351.  
  352.     vcard = property(get_vc, set_vc)
  353.     _vcard = cproperty(None, (lambda o: None if o is not None else None), (lambda o: None if o is not None else None))
  354.     
  355.     def vcard_get(self, *stuffs):
  356.         if self.vcard:
  357.             stuff = stuffs[0]
  358.             stuffs = stuffs[1:]
  359.             thing = getattr(self.vcard, stuff, None)
  360.             if isinstance(thing, list) and thing:
  361.                 thing = thing[0]
  362.                 while stuffs:
  363.                     thing = getattr(thing, stuffs[0])
  364.                     stuffs = stuffs[1:]
  365.             elif thing:
  366.                 if stuffs:
  367.                     log.warning_s('%r', stuffs)
  368.                     log.warning_s(self.vcard.as_xml())
  369.                 
  370.             
  371.             return None if thing else thing
  372.         
  373.  
  374.     nick = cproperty(None)
  375.     
  376.     def _incoming_icon(self, photos):
  377.         if photos and photos[0].image:
  378.             img = photos[0].image
  379.             self._update_photo_image(img)
  380.         elif photos and photos[0].uri:
  381.             
  382.             def success(result):
  383.                 (_response, content) = result
  384.                 self._update_photo_image(content)
  385.  
  386.             meth = threaded(urlcacheopen)
  387.             meth.verbose = False
  388.             meth(photos[0].uri, success = success)
  389.         
  390.  
  391.     
  392.     def _update_photo_image(self, data):
  393.         hash = hashlib.sha1(data).hexdigest()
  394.         self.cache_icon(data, hash)
  395.         self.icon_hash = hash
  396.  
  397.     
  398.     def get_remote_alias(self):
  399.         for attr in ('rostername', 'nick'):
  400.             nick = getattr(self, attr, None)
  401.             if nick:
  402.                 return unicode(nick)
  403.                 continue
  404.         
  405.         for attr in ('nickname', 'fn'):
  406.             nick = self.vcard_get(attr)
  407.             if nick:
  408.                 return unicode(nick)
  409.                 continue
  410.         
  411.  
  412.     remote_alias = oproperty(get_remote_alias, observe = [
  413.         'vcard'])
  414.     
  415.     def add_to_group(self, groupname, callback = None):
  416.         log.info('%s add_to_group %s', self, groupname)
  417.         pending = self.pending_adds
  418.         if groupname in pending:
  419.             log.info('ignoring request.')
  420.         else:
  421.             pending.add(groupname)
  422.         item = self.protocol.roster.get_item_by_jid(self.id).clone()
  423.         if groupname not in item.groups:
  424.             item.groups.append(groupname)
  425.             query = item.make_roster_push()
  426.             
  427.             def onsuccess(_s):
  428.                 pending.discard(groupname)
  429.                 callback.success()
  430.  
  431.             
  432.             def onerror(_s = (None, (None, None, None), None)):
  433.                 pending.discard(groupname)
  434.                 log.warning('error adding %r to %s', self.id, groupname)
  435.  
  436.             self.protocol.send_cb(query, success = onsuccess, error = onerror, timeout = onerror)
  437.         
  438.  
  439.     add_to_group = action(needs = ((unicode, 'Group name'),))(callsback(add_to_group))
  440.     
  441.     def remove(self, callback = None):
  442.         
  443.         try:
  444.             item = self.protocol.roster.get_item_by_jid(self.id).clone()
  445.         except KeyError:
  446.             return None
  447.  
  448.         item.subscription = 'remove'
  449.         self.protocol.send_cb(item.make_roster_push(), callback = callback)
  450.  
  451.     remove = action()(callsback(remove))
  452.     
  453.     def subscribed(self):
  454.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribed'))
  455.  
  456.     subscribed = action((lambda self: if no_widget(self) is None:
  457. passelif self.subscription in SUBSCRIPTION_FROM:
  458. passTrue))(subscribed)
  459.     
  460.     def unsubscribed(self):
  461.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribed'))
  462.  
  463.     unsubscribed = action((lambda self: if no_widget(self) is None:
  464. passelif self.subscription not in SUBSCRIPTION_FROM:
  465. passTrue))(unsubscribed)
  466.     
  467.     def subscribe(self):
  468.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribe'))
  469.  
  470.     subscribe = action((lambda self: if no_widget(self) is None:
  471. passelif self.subscription in SUBSCRIPTION_TO:
  472. passTrue))(subscribe)
  473.     
  474.     def unsubscribe(self):
  475.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribe'))
  476.  
  477.     unsubscribe = action((lambda self: if no_widget(self) is None:
  478. passelif self.subscription not in SUBSCRIPTION_TO:
  479. passTrue))(unsubscribe)
  480.     
  481.     def appear_offline_to(self):
  482.         self.protocol.send_presence(Presence(stanza_type = 'unavailable', status = 'Logged Out', to_jid = self.id))
  483.  
  484.     
  485.     def expand(self):
  486.         print 'expand %r' % self
  487.  
  488.     expand = action()(expand)
  489.     
  490.     def sorted_resources(self):
  491.         return sorted(self.resources.itervalues(), key = (lambda r: (r.priority, r.jid)), reverse = True)
  492.  
  493.     
  494.     def __iter__(self):
  495.         return iter(self.sorted_resources())
  496.  
  497.     
  498.     def __len__(self):
  499.         return len(self.resources)
  500.  
  501.     
  502.     def __getitem__(self, index):
  503.         return self.sorted_resources()[index]
  504.  
  505.     
  506.     def __repr__(self):
  507.         
  508.         try:
  509.             res = len(self.resources)
  510.         except:
  511.             res = 0
  512.  
  513.         
  514.         try:
  515.             n = self.name
  516.         except:
  517.             n = ''
  518.  
  519.         return '<JabberBuddy %s %d>' % (n, res)
  520.  
  521.  
  522.  
  523. def dupe_presence(p):
  524.     return Presence(p.get_node())
  525.  
  526.